//
//  DateUtils.cpp
//  Calendar
//
//  Created by 曾玮 on 14/12/11.
//
//

//#include "StdAfx.h"
#include "DateUtils.h"
#include <stdio.h>
#include <assert.h>
#include "SolarTerms.h"
#include "time.h"
using namespace std;
#include <iostream>



Date getTodayDate()
{
    auto t = time(nullptr);
    return Date(*localtime(&t));
}

bool isLeapYear(int year)
{
    if (year%4 == 0)
    {
        if (year%100 == 0)
        {
            if (year%400 == 0)
            {
                return true;
            }
            return false;
        }
        return true;
    }
    return false;
}

int daysInMon(int year, int mon)
{
    if (mon == 1 && isLeapYear(year))
    {
        return 29;
    }
    
    const int mdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    return mdays[mon];
}

void nextDate(Date& date)
{
    date.day++;
    
    int mdays = daysInMon(date.year, date.mon);
    if (date.day > mdays)
    {
        date.day = 1;
        date.mon++;
        
        if (date.mon > 11)
        {
            date.mon = 0;
            date.year++;
        }
    }
}

void prevDate(Date& date)
{
    date.day--;
    
    if (date.day <= 0)
    {
        date.mon--;
        
        if (date.mon < 0)
        {
            date.year--;
            date.mon = 11;
        }
        
        date.day = daysInMon(date.year, date.mon);
    }
}

void nextDate(Date& date, int n)
{
    assert(n >= 0);
    date.day += n;
    
    int ydays = daysInYear(date.mon < 2 ? date.year : date.year + 1);
    while (date.day > ydays)
    {
        date.day -= ydays;
        date.year++;
        ydays = daysInYear(date.mon < 2 ? date.year : date.year + 1);
    }
    
    int mdays = daysInMon(date.year, date.mon);
    while (date.day > mdays)
    {
        date.day -= mdays;
        date.mon++;
        if (date.mon > 11)
        {
            date.mon = 0;
            date.year++;
        }
        mdays = daysInMon(date.year, date.mon);
    }
}

void prevDate(Date& date, int n)
{
    assert(n >= 0);
    
    if (date.day > n)
    {
        date.day -= n;
        return;
    }
    
    n -= date.day - 1;
    date.day = 1;
    
    int ydays = daysInYear(date.mon < 2 ? date.year - 1 : date.year);
    while (n >= ydays)
    {
        n -= ydays;
        date.year--;
        ydays = daysInYear(date.mon < 2 ? date.year - 1 : date.year);
    }
    
    int mdays = daysInMon(date.year, date.mon);
    date.day = mdays;
    n += mdays - 1;
    
    while (n >= mdays)
    {
        n -= mdays;
        
        date.mon--;
        if (date.mon < 0)
        {
            date.year--;
            date.mon = 11;
        }
        
        mdays = daysInMon(date.year, date.mon);
        date.day = mdays;
    }
    date.day -= n;
}

void shiftDate(Date& date, int days)
{
    if (days > 0)
    {
        nextDate(date, days);
    }
    else
    {
        prevDate(date, -days);
    }
}

void shiftMonth(Date& date, int months)
{
    date.mon += months;
    
    if (date.mon < 0)
    {
        int delta = -(date.mon + 1);
        date.year -= 1 + delta/12;
        date.mon = 11 - delta%12;
    }
    else if (date.mon > 11)
    {
        int delta = date.mon;
        date.year += delta/12;
        date.mon = delta%12;
    }
}

int daysElapsed(const Date& from, const Date& to)
{
    // counts to Date(form.year, 0, 1)
    int days = 1 - from.day;
    for (int m = 0; m < from.mon; m++)
    {
        days -= daysInMon(from.year, m);
    }
    
    // counts to Date(to.year, 0, 1)
    if (to.year > from.year)
    {
        for (int y = from.year; y < to.year; y++)
        {
            days += daysInYear(y);
        }
    }
    else
    {
        for (int y = to.year; y < from.year; y++)
        {
            days -= daysInYear(y);
        }
    }
    
    // counts to Date(to.year, to.mon, to.day)
    for (int m = 0; m < to.mon; m++)
    {
        days += daysInMon(to.year, m);
    }
    days += to.day - 1;
    return days;
}

int getWeekDay(const Date& date)
{
#if 1 // Zeller
    int year = date.year;
    int m = date.mon + 1;
    if (m < 3)
    {
        year--;
        m += 12;
    }
    int y = year%100;
    int c = year/100;
    int w = y + y/4 + c/4 - 2*c + 26*(m + 1)/10 + date.day - 1;
    
    int r = w%7;
    return r < 0 ? 7 + r : r;
    
#else // improved Zeller?
    const int m_lut[] = { 6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
    int m = m_lut[date.mon];
    if (isLeapYear(date.year)) m--;
    
    int y = date.year%100;
    int c = date.year/100;
    int w = y/4 + y%7 - 2*(c%4) + m + date.day;
    int r = w%7;
    return r < 0 ? 7 + r : r;
    
#endif
}
// 31536000

//21600

// 24 solar terms  24节气
static long SOLAR_TERM_MIN[] =
{
    0,      21208,  42467,  63836,  85337,  107014,
    128867, 150921, 173149, 195551, 218072, 240693,
    263343, 285989, 308563, 331033, 353350, 375494,
    397447, 419210, 440795, 462224, 483532, 504758
};

#if 0
// y: year, n: solar term index, return value: date of the solar term (in month, 1~31)
int date4SolarTerm(int y, int n)
{
    //    double ms = 31556966974.7*(y - 1900) + SOLAR_TERM_MIN[n]*60000.0;
    double ms = 31556925974.7*(y - 1900) + SOLAR_TERM_MIN[n]*60000.0;
    double s = ms/1000;
    //    double sss = SOLAR_TERM_MIN[n]*60.0;
    //    double s0 = 31556926.0*(y - 1900);
    //    double s = s0 + sss;
    const long secPerDay = 86400;
    long days = s / secPerDay;
    if (s < 0)
    {
        days--;
    }
    
    Date date(1900, 0, 6);
    shiftDate(date, days);
    
    int rs = s - (double)days*secPerDay;
    //    const int theSec = 7500; // 02:05:00
    const int theSec = 7437; // 02:03:57
    
    rs += theSec;
    if (rs >= secPerDay)
    {
        rs -= secPerDay;
        nextDate(date);
    }
    
    int t = rs;
    int h = t / 3600;
    t -= h*3600;
    int m = t/60;
    int sec = t - m*60;
    
    return date.day;
}

// return solar term index, if earlier than the first solar term, return -1
int solarTerm4Date(const Date& date, bool& firstDay)
{
    static int curYear = 0;
    static int curMon = -1;
    static int termDay = 0;
    static int termDay2 = 0;
    
    int index = date.mon*2;
    //    if (curYear != date.year || curMon != date.mon)
    {
        curYear = date.year;
        curMon = date.mon;
        
        termDay = date4SolarTerm(curYear, index);
        termDay2 = date4SolarTerm(curYear, index + 1);
    }
    
    if (date.day >= termDay2)
    {
        firstDay = (date.day == termDay2);
        return index + 1;
    }
    else if (date.day >= termDay)
    {
        firstDay = (date.day == termDay);
        return index;
    }
    firstDay = false;
    return index - 1;
}

const char* getSolarTermName(int index)
{
    static const char* solarTerms[] =
    {
        "小寒", "大寒", "立春", "雨水", "惊蛰", "春分",
        "清明", "谷雨", "立夏", "小满", "芒种", "夏至",
        "小暑", "大暑", "立秋", "处暑", "白露", "秋分",
        "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"
    };
    return solarTerms[index];
}
#endif

/////////////////////////////////////////////////////////////////////////////////////////////////
//X年正月初一对应的公历年月日,结构为|---12位表示年|---4位表示月|---5位表示日|
//1900年为例,数字为0xed83f,即1110 1101 1000 0011 1111,则为1110 1101 100年0 001月1 1111日,即1900年1月31日,即1900年阴历1月1号的公历是1900年1月31号
static const unsigned int solar_1_1[225] = { 1887, 0xec04c, 0xec23f, 0xec435,                            //1887-1890
    0xec649, 0xec83e, 0xeca51, 0xecc46, 0xece3a, 0xed04d, 0xed242, 0xed436, 0xed64a, 0xed83f,           //1891-1900
    0xeda53, 0xedc48, 0xede3d, 0xee050, 0xee244, 0xee439, 0xee64d, 0xee842, 0xeea36, 0xeec4a,           //1901-1910
    0xeee3e, 0xef052, 0xef246, 0xef43a, 0xef64e, 0xef843, 0xefa37, 0xefc4b, 0xefe41, 0xf0054,           //1911-1920
    0xf0248, 0xf043c, 0xf0650, 0xf0845, 0xf0a38, 0xf0c4d, 0xf0e42, 0xf1037, 0xf124a, 0xf143e,           //1921-1930
    0xf1651, 0xf1846, 0xf1a3a, 0xf1c4e, 0xf1e44, 0xf2038, 0xf224b, 0xf243f, 0xf2653, 0xf2848,           //1931-1940
    0xf2a3b, 0xf2c4f, 0xf2e45, 0xf3039, 0xf324d, 0xf3442, 0xf3636, 0xf384a, 0xf3a3d, 0xf3c51,           //1941-1950
    0xf3e46, 0xf403b, 0xf424e, 0xf4443, 0xf4638, 0xf484c, 0xf4a3f, 0xf4c52, 0xf4e48, 0xf503c,           //1951-1960
    0xf524f, 0xf5445, 0xf5639, 0xf584d, 0xf5a42, 0xf5c35, 0xf5e49, 0xf603e, 0xf6251, 0xf6446,           //1961-1970
    0xf663b, 0xf684f, 0xf6a43, 0xf6c37, 0xf6e4b, 0xf703f, 0xf7252, 0xf7447, 0xf763c, 0xf7850,           //1971-1980
    0xf7a45, 0xf7c39, 0xf7e4d, 0xf8042, 0xf8254, 0xf8449, 0xf863d, 0xf8851, 0xf8a46, 0xf8c3b,           //1981-1990
    0xf8e4f, 0xf9044, 0xf9237, 0xf944a, 0xf963f, 0xf9853, 0xf9a47, 0xf9c3c, 0xf9e50, 0xfa045,           //1991-2000
    0xfa238, 0xfa44c, 0xfa641, 0xfa836, 0xfaa49, 0xfac3d, 0xfae52, 0xfb047, 0xfb23a, 0xfb44e,           //2001-2010
    0xfb643, 0xfb837, 0xfba4a, 0xfbc3f, 0xfbe53, 0xfc048, 0xfc23c, 0xfc450, 0xfc645, 0xfc839,           //2011-2020
    0xfca4c, 0xfcc41, 0xfce36, 0xfd04a, 0xfd23d, 0xfd451, 0xfd646, 0xfd83a, 0xfda4d, 0xfdc43,           //2021-2030
    0xfde37, 0xfe04b, 0xfe23f, 0xfe453, 0xfe648, 0xfe83c, 0xfea4f, 0xfec44, 0xfee38, 0xff04c,           //2031-2040
    0xff241, 0xff436, 0xff64a, 0xff83e, 0xffa51, 0xffc46, 0xffe3a, 0x10004e, 0x100242, 0x100437,        //2041-2050
    0x10064b, 0x100841, 0x100a53, 0x100c48, 0x100e3c, 0x10104f, 0x101244, 0x101438, 0x10164c, 0x101842, //2051-2060
    0x101a35, 0x101c49, 0x101e3d, 0x102051, 0x102245, 0x10243a, 0x10264e, 0x102843, 0x102a37, 0x102c4b, //2061-2070
    0x102e3f, 0x103053, 0x103247, 0x10343b, 0x10364f, 0x103845, 0x103a38, 0x103c4c, 0x103e42, 0x104036, //2071-2080
    0x104249, 0x10443d, 0x104651, 0x104846, 0x104a3a, 0x104c4e, 0x104e43, 0x105038, 0x10524a, 0x10543e, //2081-2090
    0x105652, 0x105847, 0x105a3b, 0x105c4f, 0x105e45, 0x106039, 0x10624c, 0x106441, 0x106635, 0x106849, //2091-2100
    0x106a3d, 0x106c51, 0x106e47, 0x10703c, 0x10724f, 0x107444, 0x107638, 0x10784c, 0x107a3f, 0x107c53, //2101-2110
    0x107e48 };

static const unsigned int lunar_month_days[225] = { 1887, 0x1694, 0x16aa, 0x4ad5,        //1887-1890
    0xab6, 0xc4b7, 0x4ae, 0xa56, 0xb52a, 0x1d2a, 0xd54, 0x75aa, 0x156a, 0x1096d,        //1891-1900
    0x95c, 0x14ae, 0xaa4d, 0x1a4c, 0x1b2a, 0x8d55, 0xad4, 0x135a, 0x495d, 0x95c,        //1901-1910
    0xd49b, 0x149a, 0x1a4a, 0xbaa5, 0x16a8, 0x1ad4, 0x52da, 0x12b6, 0xe937, 0x92e,      //1911-1920
    0x1496, 0xb64b, 0xd4a, 0xda8, 0x95b5, 0x56c, 0x12ae, 0x492f, 0x92e, 0xcc96,         //1921-1930
    0x1a94, 0x1d4a, 0xada9, 0xb5a, 0x56c, 0x726e, 0x125c, 0xf92d, 0x192a, 0x1a94,       //1931-1940
    0xdb4a, 0x16aa, 0xad4, 0x955b, 0x4ba, 0x125a, 0x592b, 0x152a, 0xf695, 0xd94,        //1941-1950
    0x16aa, 0xaab5, 0x9b4, 0x14b6, 0x6a57, 0xa56, 0x1152a, 0x1d2a, 0xd54, 0xd5aa,       //1951-1960
    0x156a, 0x96c, 0x94ae, 0x14ae, 0xa4c, 0x7d26, 0x1b2a, 0xeb55, 0xad4, 0x12da,        //1961-1970
    0xa95d, 0x95a, 0x149a, 0x9a4d, 0x1a4a, 0x11aa5, 0x16a8, 0x16d4, 0xd2da, 0x12b6,     //1971-1980
    0x936, 0x9497, 0x1496, 0x1564b, 0xd4a, 0xda8, 0xd5b4, 0x156c, 0x12ae, 0xa92f,       //1981-1990
    0x92e, 0xc96, 0x6d4a, 0x1d4a, 0x10d65, 0xb58, 0x156c, 0xb26d, 0x125c, 0x192c,       //1991-2000
    0x9a95, 0x1a94, 0x1b4a, 0x4b55, 0xad4, 0xf55b, 0x4ba, 0x125a, 0xb92b, 0x152a,       //2001-2010
    0x1694, 0x96aa, 0x15aa, 0x12ab5, 0x974, 0x14b6, 0xca57, 0xa56, 0x1526, 0x8e95,      //2011-2020
    0xd54, 0x15aa, 0x49b5, 0x96c, 0xd4ae, 0x149c, 0x1a4c, 0xbd26, 0x1aa6, 0xb54,        //2021-2030
    0x6d6a, 0x12da, 0x1695d, 0x95a, 0x149a, 0xda4b, 0x1a4a, 0x1aa4, 0xbb54, 0x16b4,     //2031-2040
    0xada, 0x495b, 0x936, 0xf497, 0x1496, 0x154a, 0xb6a5, 0xda4, 0x15b4, 0x6ab6,        //2041-2050
    0x126e, 0x1092f, 0x92e, 0xc96, 0xcd4a, 0x1d4a, 0xd64, 0x956c, 0x155c, 0x125c,       //2051-2060
    0x792e, 0x192c, 0xfa95, 0x1a94, 0x1b4a, 0xab55, 0xad4, 0x14da, 0x8a5d, 0xa5a,       //2061-2070
    0x1152b, 0x152a, 0x1694, 0xd6aa, 0x15aa, 0xab4, 0x94ba, 0x14b6, 0xa56, 0x7527,      //2071-2080
    0xd26, 0xee53, 0xd54, 0x15aa, 0xa9b5, 0x96c, 0x14ae, 0x8a4e, 0x1a4c, 0x11d26,       //2081-2090
    0x1aa4, 0x1b54, 0xcd6a, 0xada, 0x95c, 0x949d, 0x149a, 0x1a2a, 0x5b25, 0x1aa4,       //2091-2100
    0xfb52, 0x16b4, 0xaba, 0xa95b, 0x936, 0x1496, 0x9a4b, 0x154a, 0x136a5, 0xda4,       //2101-2110
    0x15ac };                                                                            //2111

/**
 * 阳历转阴历
 * 注意此方法的输入和返回月份为1-12
 *
 * @param solar 阳历日期
 * @return 对应的阴历日期
 */
LunarDate solar2Lunar(const Date& solar)
{
    LunarDate lunar;
    //先把月份改为1-12
    int year = solar.year;
    int month = solar.mon + 1;
    int day = solar.day;
    int index = year - solar_1_1[0];
    int data = (year << 9) | (month << 5) | (day);
    int solar11 = 0;
    if (solar_1_1[index] > data) {
        index--;
    }
    solar11 = solar_1_1[index];
    int y = getBitInt(solar11, 12, 9);
    int m = getBitInt(solar11, 4, 5);
    int d = getBitInt(solar11, 5, 0);
    long offset = solarToInt(year, month, day) - solarToInt(y, m, d);
    
    int days = lunar_month_days[index];
    int leap = getBitInt(days, 4, 13);
    
    int lunarY = index + solar_1_1[0];
    int lunarM = 1;
    int lunarD = 1;
    offset += 1;
    
    for (int i = 0; i < 13; i++) {
        int dm = getBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
        if (offset > dm) {
            lunarM++;
            offset -= dm;
        }
        else {
            break;
        }
    }
    lunarD = (int)(offset);
    lunar.year = lunarY;
    lunar.mon = lunarM;
    //此月是否为闰月
    bool isleap = false;
    if (leap != 0 && lunarM > leap) {
        lunar.mon = lunarM - 1;
        if (lunarM == leap + 1) {
            isleap = true;
        }
    }
    //月份改为0-11
    lunar.mon = lunar.mon - 1;
    lunar.day = lunarD;
    lunar.leapMonth = isleap;
    return lunar;
}

/**
 * 左移shift位然后截取length长度的bit值得到的值
 * 注意返回的值是length个bit位的值
 *
 * @param data   对应的int值
 * @param length 截取的bit位长度
 * @param shift  左移位数
 */
int getBitInt(int data, int length, int shift) {
    return (data & (((1 << length) - 1) << shift)) >> shift;
}

/**
 * 获取阳历对应的天数
 *
 * @param year  年
 * @param month 月
 * @param day   日
 */
long solarToInt(int year, int month, int day) {
    month = (month + 9) % 12;
    year = year - month / 10;
    return 365 * year + year / 4 - year / 100 + year / 400 + (month * 306 + 5) / 10 + (day - 1);
}

const char* getLunarDateName(const LunarDate& date)
{
    const char* monNames[] =
    {
        "正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "腊月",
    };
    
    const char* dayNames[] =
    {
        "***", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
        "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
        "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十",
    };
    
    if (date.day < 1 || date.day > 30 || date.mon < 0 || date.mon > 11)
    {
        return "***";
    }
    
    if (date.day == 1)
    {
        return monNames[date.mon];
    }
    else
    {
        char buffer[128] = {0};
        sprintf(buffer, "%s,%s", monNames[date.mon], dayNames[date.day - 1]);
        
        //string name = monNames[date.mon];
        //string name = monNames[date.mon];
        //name += dayNames[date.day - 1];
        //name += "宿";
        return buffer;
    }
}


string getLunarDateNameNew(const LunarDate& date)
{
    const char* monNames[] =
    {
        "正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "腊月",
    };
    
    const char* dayNames[] =
    {
        "***", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
        "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
        "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十",
    };
    
    if (date.day < 1 || date.day > 30 || date.mon < 0 || date.mon > 11)
    {
        return "***";
    }
    
    if (date.day == 1)
    {
        return monNames[date.mon];
    }
    else
    {
        string name = monNames[date.mon];
        //string name = monNames[date.mon];
        name += dayNames[date.day - 1];
        //name += "宿";
        return name;
    }
}




void getLunarDateNameMD(const LunarDate& date, char* buf, int len)
{
    const char* monNames[] =
    {
        "正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "腊月",
    };
    
    const char* dayNames[] =
    {
        "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
        "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
        "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十",
    };
    
    //   snprintf(buf, len, "农历%s%s", monNames[date.mon], dayNames[date.day - 1]);
}

static inline int getMod(int i, int cnt)
{
    i %= cnt;
    return i < 0 ? i + cnt : i;
}

//甲子年

/*
 int getYearSB(const Date& date)
 {
 int i = date.year - 1984;
 
 int st = solarTerm4Date(date);
 if (st >= 2) // passed 立春
 {
 return getMod(i, 60);
 }
 return getMod(i-1, 60);
 }
 */

//获取年的甲子,此日期为阴历日期
int getYearSB(const Date& date)
{
    LunarDate ld = solar2Lunar(date);
    int i = ld.year - 1984;
    
    return getMod(i, 60);
}


//甲子月
int getMonSB(const Date& date)
{
    int i = (date.year-2013)*12 + date.mon - 11;
    
    int st = solarTerm4Date(date);
    cout << "#####################" << endl;
    printf("getMonsb2");
    printf("getMonsb2");
    printf("i");
    cout << i << endl;
    printf("st");
    cout << st << endl;
    printf("date.mon");
    cout << date.mon << endl;
    cout << "#####################" << endl;
    if (st/2 == date.mon) // passed the first solar term
    {
        return getMod(i, 60);
    }
    return getMod(i-1, 60);
}


//甲子日
int getDaySB(const Date& date)
{
    
    int i = daysElapsed(Date(2013, 12-1, 24), date);
    return getMod(i, 60);
}



//获取小时的甲子
int getHourSB(const Date& date,int hour){
    
    int dayStem = getDaySB(date) % 10;
    int i = dayStem*12 + (hour + 1)/2;
    return getMod(i, 60);
}

/**
	1900年1月1日为甲戌日，按照下列数组60天一个循环，即可计算出给定日期的日子
	@param sbIndex为 给定日期与1900年1月1日差值对60取模
 */
const char* getSBName(int sbIndex)
{
    static const char* tab[] =
    {
        "甲子", "乙丑", "丙寅", "丁卯", "戊辰", "己巳", "庚午", "辛未", "壬申", "癸酉",
        "甲戌", "乙亥", "丙子", "丁丑", "戊寅", "己卯", "庚辰", "辛巳", "壬午", "癸未",
        "甲申", "乙酉", "丙戌", "丁亥", "戊子", "己丑", "庚寅", "辛卯", "壬辰", "癸巳",
        "甲午", "乙未", "丙申", "丁酉", "戊戌", "己亥", "庚子", "辛丑", "壬寅", "癸卯",
        "甲辰", "乙巳", "丙午", "丁未", "戊申", "己酉", "庚戌", "辛亥", "壬子", "癸丑",
        "甲寅", "乙卯", "丙辰", "丁巳", "戊午", "己未", "庚申", "辛酉", "壬戌", "癸亥",
    };
    return tab[sbIndex];
}



/*#################################################################################幸运方位###########################################################################################*/
//是否为闰年
bool isleapyear(int y){
    return (y % 4 == 0 && y % 100 || y % 400 == 0);
}

//求总天数
int sum(int y, int m, int d){
    int md[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int cnt = y * 365;
    cnt += (y - 1) / 4 + 1;
    cnt -= (y - 1) / 100 + 1;
    cnt += (y - 1) / 400 + 1;
    for (int i = 1; i < m; ++i) cnt += md[i];
    if (m > 2 && isleapyear(y)) ++cnt;
    cnt += d;
    return cnt;
}
//计算差值
int Count(int y1, int m1, int d1, int y2, int m2, int d2){
    return sum(y2, m2, d2) - sum(y1, m1, d1);
}

//计算所求日期到1899年12月22日相差多少天
int DaysBetween2Date(int year2, int month2, int day2)
{
    return Count(1899, 12, 22, year2, month2,day2);
}

